package com.anycc.cloud.core.entity;

import com.anycc.cloud.common.entity.BaseEntity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 模块实体类
 */
@Entity
@Table(
        name = "sys_module",
        indexes = {@Index(
                name = "i_sys_module_name",
                columnList = "name"
        ), @Index(
                name = "i_sys_module_sn",
                columnList = "sn"
        ), @Index(
                name = "i_sys_module_priority",
                columnList = "priority"
        )}
)
public class Module extends BaseEntity implements Comparable<Module> {
    private static final long serialVersionUID = 8711770479183416379L;
    public static final String FIELD_NAME = "name";
    public static final String FIELD_SN = "sn";
    public static final String FIELD_PRIORITY = "priority";
    public static final String FIELD_ICON = "icon";
    public static final String FIELD_TARGET = "target";
    public static final String FIELD_DESCRIPTION = "description";
    public static final String FIELD_PARENT = "parent";
    public static final String FIELD_CHILDREN = "children";
    public static final String FIELD_PERMISSIONS = "permissions";
    private String name;
    private String sn;
    private Integer priority = 999;
    private String icon;
    private String target;
    private String description;
    private Module parent;
    private List<Module> children = new ArrayList<>();
    private List<Permission> permissions = new ArrayList<>();

    public Module() {
    }

    @Column(
            name = "name",
            length = 64,
            nullable = false
    )
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(
            name = "sn",
            length = 36,
            nullable = false,
            unique = true
    )
    public String getSn() {
        return this.sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    @Column(
            name = "priority",
            nullable = false
    )
    public Integer getPriority() {
        return this.priority;
    }

    public void setPriority(Integer priority) {
        this.priority = priority;
    }

    @Column(
            name = "icon",
            length = 64
    )
    public String getIcon() {
        return this.icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    @Column(
            name = "target",
            length = 16
    )
    public String getTarget() {
        return this.target;
    }

    public void setTarget(String target) {
        this.target = target;
    }

    @Column(
            name = "description",
            length = 256
    )
    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @ManyToOne
    @JoinColumn(
            name = "parent_id"
    )
    @JsonIgnoreProperties({"parent", "children", "permissions", "updateTime", "createTime"})
    public Module getParent() {
        return this.parent;
    }

    public void setParent(Module parent) {
        this.parent = parent;
    }

    @JsonIgnore
    @OneToMany(
            mappedBy = "parent"
    )
    @OrderBy("priority")
    public List<Module> getChildren() {
        return this.children;
    }

    public void setChildren(List<Module> children) {
        this.children = children;
    }

    @OneToMany(
            mappedBy = "module",
            cascade = {CascadeType.ALL},
            orphanRemoval = true
    )
    @JsonIgnoreProperties({"updateTime", "createTime"})
    @OrderBy("name DESC")
    public List<Permission> getPermissions() {
        return this.permissions;
    }

    public void setPermissions(List<Permission> permissions) {
        this.permissions = permissions;
    }

    public int compareTo(Module o) {
        return o != null && this.priority.intValue() >= o.getPriority().intValue() ? (o == this ? 0 : (this.priority.intValue() > o.getPriority().intValue() ? 1 : 0)) : -1;
    }

    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this, new String[0]);
    }

    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj, new String[0]);
    }
}